﻿Imports System.Runtime.CompilerServices
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

Public Module GraphicsExtensions

	Function RoundRectPath(ByVal Rect As Rectangle, ByVal ArcSize As Integer, Optional ByVal Borders As String = "tlrb") As GraphicsPath
		Dim Path As New GraphicsPath
		With Path
			.StartFigure()
			Dim Bottom As Integer = Rect.Y + Rect.Height - ArcSize
			Dim Right As Integer = Rect.X + Rect.Width - ArcSize
			If Len(Borders) = 4 Then
				.AddArc(New Rectangle(Rect.X, Rect.Y, ArcSize, ArcSize), 180, 90)
				.AddArc(New Rectangle(Right, Rect.Y, ArcSize, ArcSize), 270, 90)
				.AddArc(New Rectangle(Right, Bottom, ArcSize, ArcSize), 0, 90)
				.AddArc(New Rectangle(Rect.X, Bottom, ArcSize, ArcSize), 90, 90)
				.CloseFigure()
			Else
				Select Case Borders
					Case "tl", "lt"
						.AddArc(New Rectangle(Rect.X, Bottom, ArcSize, ArcSize), 135, 45)
						.AddArc(New Rectangle(Rect.X, Rect.Y, ArcSize, ArcSize), 180, 90)
						.AddArc(New Rectangle(Right, Rect.Y, ArcSize, ArcSize), 270, 45)
					Case "br", "rb"
						.AddArc(New Rectangle(Right, Rect.Y, ArcSize, ArcSize), 315, 45)
						.AddArc(New Rectangle(Right, Bottom, ArcSize, ArcSize), 0, 90)
						.AddArc(New Rectangle(Rect.X, Bottom, ArcSize, ArcSize), 90, 45)
				End Select
			End If
		End With
		Return Path
	End Function

	Function RoundRectPath(ByVal Rect As Rectangle, ByVal ArcTL As Integer, ByVal ArcTR As Integer, ByVal ArcBR As Integer, ByVal ArcBL As Integer) As GraphicsPath
		If ArcTL < 0 Then ArcTL = 0
		If ArcTR < 0 Then ArcTR = 0
		If ArcBL < 0 Then ArcBL = 0
		If ArcBR < 0 Then ArcBR = 0
		Dim Path As New GraphicsPath
		With Path
			.StartFigure()
			If ArcTL > 0 Then .AddArc(New Rectangle(Rect.X, Rect.Y, ArcTL, ArcTL), 180, 90) Else .AddLine(Rect.Left, Rect.Bottom - ArcBL, Rect.X, Rect.Y + ArcTL)
			If ArcTR > 0 Then .AddArc(New Rectangle(Rect.Right - ArcTR, Rect.Y, ArcTR, ArcTR), 270, 90) Else .AddLine(Rect.Right - ArcTR, Rect.Y, Rect.X + ArcTL, Rect.Y)
			If ArcBR > 0 Then .AddArc(New Rectangle(Rect.Right - ArcBR - 1, Rect.Bottom - ArcBR - 1, ArcBR + 1, ArcBR + 1), 0, 90) Else .AddLine(Rect.Right, Rect.Y + ArcTR, Rect.Right, Rect.Bottom - ArcBR)
			If ArcBL > 0 Then .AddArc(New Rectangle(Rect.X, Rect.Bottom - ArcBL - 1, ArcBL + 1, ArcBL + 1), 90, 90) Else .AddLine(Rect.Right - ArcBR, Rect.Bottom, Rect.X + ArcBL, Rect.Bottom)
			.CloseFigure()
		End With
		Return Path
	End Function

	<Extension()> _
	Public Sub DrawRoundRect(ByVal Gr As Graphics, ByVal Pen As Pen, ByVal Rect As Rectangle, ByVal ArcSize As Integer, ByVal Borders As String)
		If ArcSize = 0 Then
			Gr.DrawRectangle(Pen, Rect)
			Exit Sub
		End If
		Dim Path As GraphicsPath = RoundRectPath(Rect, ArcSize, Borders)
		Gr.DrawPath(Pen, Path)
	End Sub

	<Extension()> _
	Public Sub DrawRoundRect(ByVal Gr As Graphics, ByVal Pen As Pen, ByVal Rect As Rectangle, ByVal ArcSize As Integer)
		Gr.DrawRoundRect(Pen, Rect, ArcSize, "tlbr")
	End Sub

	<Extension()> _
	Public Sub DrawRoundRect(ByVal Gr As Graphics, ByVal Pen As Pen, ByVal Rect As Rectangle, ByVal ArcTL As Integer, ByVal ArcTR As Integer, ByVal ArcBR As Integer, ByVal ArcBL As Integer)
		Dim Path As GraphicsPath = RoundRectPath(Rect, ArcTL, ArcTR, ArcBR, ArcBL)
		Gr.DrawPath(Pen, Path)
	End Sub

	<Extension()> _
	Public Sub FillRoundRect(ByVal Gr As Graphics, ByVal Brush As Brush, ByVal Rect As Rectangle, ByVal ArcSize As Integer)
		Dim Path As GraphicsPath = RoundRectPath(Rect, ArcSize, "tlbr")
		Gr.FillPath(Brush, Path)
	End Sub

	<Extension()> _
	Public Sub FillRoundRect(ByVal Gr As Graphics, ByVal Brush As Brush, ByVal Rect As Rectangle, ByVal ArcTL As Integer, ByVal ArcTR As Integer, ByVal ArcBR As Integer, ByVal ArcBL As Integer)
		Dim Path As GraphicsPath = RoundRectPath(Rect, ArcTL, ArcTR, ArcBR, ArcBL)
		Gr.FillPath(Brush, Path)
	End Sub

	<Extension()>
	Public Sub DrawText(ByVal Gr As Graphics, ByVal Text As String, ByVal Font As Font, ByVal Rect As Rectangle, ByVal Color As Color, ByVal Flags As String)
		Dim Align = TextFormatFlags.HorizontalCenter
		Dim Valign = TextFormatFlags.VerticalCenter
		If Flags.Contains("l") Then Align = TextFormatFlags.Left
		If Flags.Contains("r") Then Align = TextFormatFlags.Right
		If Flags.Contains("t") Then Valign = TextFormatFlags.Top
		If Flags.Contains("b") Then Valign = TextFormatFlags.Bottom
		Dim F As TextFormatFlags = Align Or Valign Or TextFormatFlags.PreserveGraphicsTranslateTransform
		If Flags.Contains("w") Then F = F Or TextFormatFlags.WordBreak
		TextRenderer.DrawText(Gr, Text, Font, Rect, Color, Drawing.Color.Transparent, F)
	End Sub

	<Extension()>
	Public Sub DrawText(ByVal Gr As Graphics, ByVal Text As String, ByVal Font As Font, ByVal Rect As Rectangle, ByVal Color As Color, ByVal Flags As TextFormatFlags)
		TextRenderer.DrawText(Gr, Text, Font, Rect, Color, Drawing.Color.Transparent, Flags)
	End Sub

	<Extension()>
	Public Function MeasureText(ByVal Gr As Graphics, ByVal Text As String, ByVal Font As Font, ByVal Size As Size, Optional ByVal Flags As TextFormatFlags = 0) As Size
		Return TextRenderer.MeasureText(Gr, Text, Font, Size, Flags Or TextFormatFlags.PreserveGraphicsClipping)
	End Function

	<Extension()>
	Public Function Opacity(ByVal c As Color, ByVal Alpha As Integer) As Color
		Return Color.FromArgb(Alpha, c)
	End Function

	<Extension()>
	Public Function Brush(ByVal c As Color) As Brush
		Return New SolidBrush(c)
	End Function

	<Extension()>
	Public Function Pen(ByVal c As Color) As Pen
		Return New Pen(c)
	End Function

	<Extension()>
	Public Function HasNeighbor(ByVal t As ToolStrip, ByVal Item As ToolStripItem, ByVal d As Integer) As Boolean
		Dim i = t.Items.IndexOf(Item)
		Do
			i += If(Item.Alignment = ToolStripItemAlignment.Left, d, -d)
			If i < 0 Then Return True
			If i > t.Items.Count - 1 Then Return True
			If Item.Alignment <> t.Items(i).Alignment Then Return True
			If t.Items(i).Visible Then Return TypeOf t.Items(i) Is ToolStripSeparator
		Loop
		Return False
	End Function

	<Extension()>
	Function Addresses(ByVal m As Microsoft.VisualBasic.Devices.Network) As List(Of String)
		Return (From x In System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList Select IP = x.ToString).ToList
	End Function

End Module

Public Class StringFormats

	Public Shared ReadOnly Property Centered As StringFormat
		Get
			Dim F As New StringFormat
			F.Alignment = StringAlignment.Center
			F.LineAlignment = StringAlignment.Center
			Return F
		End Get
	End Property

End Class

